package com.sinodata.bsm.center.service.resource;

import java.math.BigDecimal;
import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sinodata.bsm.center.bean.Condition;
import com.sinodata.bsm.center.bean.Page;
import com.sinodata.bsm.center.bean.RelationHelper;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.cache.*;
import com.sinodata.bsm.center.dao.BaseDao;
import com.sinodata.bsm.center.dao.impl.ResAttrValHisDaoImpl;
import com.sinodata.bsm.center.dao.impl.ResDaoImpl;
import com.sinodata.bsm.center.engine.probe.ProbeStatusManager;
import com.sinodata.bsm.center.engine.resource.health.ResHealthEngine;
import com.sinodata.bsm.center.message.ProbeMessenger;
import com.sinodata.bsm.center.service.event.EventRuleService;
import com.sinodata.bsm.center.service.relation.ResRelationService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.constants.RelationConstants;
import com.sinodata.bsm.common.exception.AppException;
import com.sinodata.bsm.common.vo.*;

@Service
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class ResGroupService {
    @Autowired
    private ResCache resCache;
    @Autowired
    private ResGroupCache resGroupCache;
    @Autowired
    private BaseDao baseDao;
    @Autowired
    private ResTypeCache resTypeCache;

    @Autowired
    private MotiResRelCache motiResRelCache;

    public ResGroup get(Long id) {
        return resGroupCache.get(id);
    }

    /**
     * 自动添加应用系统的资源组
     * @param resId
     */
    public void saveApplicationGroup(Long resId) {
        saveAppServie(resId, "应用服务", null, 1000L);
        //应用资源
        ResGroup appGroup = saveAppServie(resId, "应用环境", null, null);
        saveAppServie(resId, "进程", appGroup.getId(), 1010L);
        saveAppServie(resId, "端口", appGroup.getId(), 1020L);
        saveAppServie(resId, "日志文件", appGroup.getId(), 1030L);
        saveAppServie(resId, "SQL查询", appGroup.getId(), 1040L);
        saveAppServie(resId, "脚本", appGroup.getId(), 1050L);
        //基础资源
        ResGroup baseGroup = saveAppServie(resId, "基础资源", null, null);
        saveAppServie(resId, "主机", baseGroup.getId(), 2000L);
        saveAppServie(resId, "数据库", baseGroup.getId(), 2100L);
        saveAppServie(resId, "中间件", baseGroup.getId(), 2200L);
        saveAppServie(resId, "虚拟化", baseGroup.getId(), 2300L);
        //        //接口关联
        //        saveAppServie(resId,"系统关联",null,null);
        saveAppServie(resId, "接口关联", null, 100L);
    }

    private ResGroup saveAppServie(Long resId, String name, Long pId, Long containType) {
        ResGroup g = new ResGroup();
        g.setName(name);
        if (pId != null) {
            g.setParentId(pId);
        }
        g.setContainType(containType);
        g.setResId(resId);
        g.setType(2);
        saveOrUpdateResGroup(g);
        return g;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrUpdateResGroup(ResGroup _ressGroup) {
        baseDao.saveOrUpdate(_ressGroup);
        resGroupCache.put(_ressGroup);
    }

    /**
     * 删除资源组
     * @param _ressGroup
     * @throws AppException
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteResGroup(ResGroup _ressGroup) throws AppException {
        List<MotiResRel> relList = motiResRelCache.findByResGroupId(_ressGroup.getId());
        if (relList != null && relList.size() > 0) {
            throw new AppException("资源组已关联资源，不能删除。resGroupId:" + _ressGroup.getId());
        }
        resGroupCache.remove(_ressGroup);
        baseDao.delete(_ressGroup);
    }

    /**
     * 保存 resGroup 与 resId的关系
     * @param _motiResRel
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveMotiResRel(MotiResRel _motiResRel) throws AppException {
        long groupid = _motiResRel.getResGroupId();
        ResGroup group = get(groupid);
        if (group.getMonitorTypeId() != null) {
            long resid = _motiResRel.getResId();
            Res res = resCache.get(resid);
            Long mtId = resTypeCache.getMoitTypeId(res.getResTypeId());
            if (mtId == null || mtId.longValue() != group.getMonitorTypeId()) {
                throw new AppException("关联资源错误,resId:" + resid);
            }
        }
        baseDao.save(_motiResRel);
        motiResRelCache.put(_motiResRel);
    }

    /**
     * 删除 resGroup 与 resId的关系
     * @param _motiResRel
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteMotiResRel(long groupid, long resid) {
        MotiResRel _motiResRel = motiResRelCache.remove(groupid, resid);
        if (_motiResRel != null) {
            baseDao.delete(_motiResRel);
        }
    }

}
